package com.system.healthproject.model.sickuser.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.system.healthproject.annotation.RequireToken;
import com.system.healthproject.bean.DoctorInfo;
import com.system.healthproject.bean.PagesBean;
import com.system.healthproject.bean.ReactionParams;
import com.system.healthproject.bean.web.ResultOrder;
import com.system.healthproject.common.ApiResult;
import com.system.healthproject.mapper.CardOrderMapper;
import com.system.healthproject.model.admin.paramsbean.*;
import com.system.healthproject.model.sickuser.params.UserDoctorsItem;
import com.system.healthproject.model.sickuser.params.UserEditPatientParams;
import com.system.healthproject.model.sickuser.params.UserPatientInfo;
import com.system.healthproject.model.sickuser.params.UserRegisterPhone;
import com.system.healthproject.model.sickuser.service.SickUserServices;
import com.system.healthproject.model.sickuser.service.UserAppCodeService;
import com.system.healthproject.utils.AlipayConfig;
import com.system.healthproject.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Api(value = "患者端-用户",tags = "患者端-用户管理API")
@RestController
@Validated
@RequestMapping("/sickuser/user")
public class SickUserController {

    @Autowired
    SickUserServices sickUserService;
    @Autowired
    UserAppCodeService userAppCodeService;
    @Autowired
    RedisUtil redisUtil;



    @ApiOperation(value = "患者端用户登录接口(后台已调)",notes = "验证患者端用户的用户名和密码",httpMethod = "post")
    @PostMapping(value = "/login",produces = "application/json;charset=utf-8")
    public ApiResult<String> login(@RequestBody
             @ApiParam(name = "user",value = "患者端用户名和密码",required = true) LoginParams loginParams){
        String token = sickUserService.login(loginParams);
        if(token!=null){
            return ApiResult.successWithData("成功",token);
        }else {
            return ApiResult.failure("登录失败,请重新输入");
        }
    }

    @ApiOperation(value = "患者端用户注册接口(后台已调)",notes = "患者端注册",httpMethod = "post")
    @PostMapping(value = "/register",produces = "application/json;charset=utf-8")
    public ApiResult register(@RequestBody
                                   @ApiParam(name = "user",value = "患者端用户名和密码",required = true)
                                      UserRegisterPhone loginParams){
        Boolean register = sickUserService.register(loginParams);
        return ApiResult.withBoolean(register,"注册成功","注册失败");
    }

    @ApiOperation(value = "患者修改患者信息(后端已调)",httpMethod = "post")
    @PostMapping(value = "/userEditPatient",produces = "application/json;charset=utf-8")
    public ApiResult userEditPatient(
            @RequestBody
            @ApiParam(required = true) UserEditPatientParams patientDoctor
    ,@RequestHeader("token")String token){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");
        boolean b = sickUserService.userEditPatient(patientDoctor,loginId);
        return ApiResult.withBoolean(b,"修改成功","修改失败");
    }

    @ApiOperation(value = "患者获取患者详情(后端已调)",httpMethod = "get")
    @GetMapping(value = "/userPatientInfo",produces = "application/json;charset=utf-8")
    public ApiResult<PatientInfo> userPatientInfo(@RequestHeader("token")String token){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");

        PatientInfo patientInfo = sickUserService.userPatientInfo(loginId);
        return ApiResult.successWithData(patientInfo);
    }

    @RequireToken
    @ApiOperation(value = "患者端添加发作次数(后台已调)",notes = "患者端添加发作次数",httpMethod = "post")
    @PostMapping(value = "/addFrequency",produces = "application/json;charset=utf-8")
    public ApiResult addFrequency(
                    @NotNull Integer frequencyNumber,
    @RequestHeader("token")String token){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");
        Boolean register = sickUserService.addFrequency(frequencyNumber,loginId);
        return ApiResult.withBoolean(register);
    }

    @RequireToken
    @ApiOperation(value = "患者端添加症状记录(后台已调)",notes = "患者端添加发作次数",httpMethod = "post")
    @PostMapping(value = "/addReactions",produces = "application/json;charset=utf-8")
    public ApiResult addReactions(
            @Validated
            @RequestBody ReactionParams reactionParams,
            @RequestHeader("token")String token){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");
        return sickUserService.addReactions(reactionParams,loginId);
    }


    @RequireToken
    @ApiOperation(value = "患者端扫描后台二维码接口(后台已调)",notes = "患者端扫描后台二维码接口",httpMethod = "post")
    @PostMapping(value = "/useCode",produces = "application/json;charset=utf-8")
    public ApiResult useCode(
            @NotNull
            Integer appCodeId,
            @RequestHeader("token")String token
    ){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");
        boolean b = userAppCodeService.useCode(appCodeId, loginId);
        return ApiResult.withBoolean(b,"使用二维码成功","使用二维码失败");
    }
    @RequireToken
    @ApiOperation(value = "患者绑定医生(后端已调)",notes = "患者绑定医生接口(如果显示401就表示已绑定医生)",httpMethod = "post")
    @PostMapping(value = "/bingDoctor",produces = "application/json;charset=utf-8")
    public ApiResult bingDoctor(
            @NotNull
            Integer doctorId ,
            @RequestHeader("token")String token){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");

        ApiResult apiResult = sickUserService.bindDoctor(loginId, doctorId);
        return apiResult;
    }

    @RequireToken
    @ApiOperation(value = "患者获取医生详情(后端已调)",notes = "患者获取医生详情接口",httpMethod = "get")
    @GetMapping(value = "/userGetDoctorInfoById",produces = "application/json;charset=utf-8")
    public ApiResult<DoctorInfo> userGetDoctorInfoById(
            @NotNull
            @RequestParam(value = "doctorId",required = false)
            Integer doctorId ,
            @RequestHeader("token")String token){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");

        DoctorInfo doctorInfo = sickUserService.userGetDoctorInfoById(loginId, doctorId);
        Integer doctorId1 = doctorInfo.getDoctorId();
        if(doctorId1!=null){
            return ApiResult.successWithData(doctorInfo);
        }else {
            return ApiResult.failure("获取详情失败,请重新上传");
        }
    }

    @RequireToken
    @ApiOperation(value = "获取患者详情(后端已调)",notes = "获取患者详情",httpMethod = "get")
    @GetMapping(value = "/getPatientInfo",produces = "application/json;charset=utf-8")
    public ApiResult<UserPatientInfo> getPatientInfo(
            @RequestHeader("token")String token){

        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");
        UserPatientInfo patientInfo = sickUserService.getPatientInfo(loginId);
        return ApiResult.successWithData(patientInfo);
    }


    @RequireToken
    @ApiOperation(value = "患者获取发作次数(后台已调)",notes = "患者获取发作次数",httpMethod = "get")
    @GetMapping(value = "/userGetFrequencyList",produces = "application/json;charset=utf-8")
    public ApiResult<List<FrequencyParams>>  userGetFrequencyList(
            @RequestHeader("token")String token,
            @NotNull @RequestParam(value = "type",required = false) Integer type){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");

        List<FrequencyParams> frequencyParams = sickUserService.userGetFrequencyList(loginId,type);
        return ApiResult.successWithData(frequencyParams);
    }

    @RequireToken
    @ApiOperation(value = "患者获取症状列表(后台已调)",notes = "患者获取症状列表",httpMethod = "get")
    @GetMapping(value = "/userGetReactions",produces = "application/json;charset=utf-8")
    public ApiResult<List<ReactionsParams> >   userGetReactions(
            @RequestHeader("token")String token,
            @NotNull@RequestParam(value = "type",required = false) Integer type){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");

        List<ReactionsParams> reactionsParams = sickUserService.userGetReactions(loginId,type);
        return ApiResult.successWithData(reactionsParams);
    }


    @RequireToken
    @ApiOperation(value = "患者获取就诊记录(后台已调)",notes = "患者获取就诊记录",httpMethod = "get")
    @GetMapping(value = "/userGetVisitRecordsList",produces = "application/json;charset=utf-8")
    public ApiResult<PagesBean<VisitRecordsShowParams>> userGetVisitRecordsList(
            @NotNull Integer page,
            @NotNull Integer size,
            @RequestHeader("token")String token
    ){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");

        PagesBean<VisitRecordsShowParams> visitRecordsShowParamsPagesBean
                = sickUserService.userGetVisitRecordsList(page, size, loginId);
        return ApiResult.successWithData(visitRecordsShowParamsPagesBean);
    }

    @RequireToken
    @ApiOperation(value = "患者获取病例详情(后台已调)",notes = "患者获取病例详情",httpMethod = "get")
    @GetMapping(value = "/userGetRecordInfo",produces = "application/json;charset=utf-8")
    public ApiResult<RecordInfoParams> userGetRecordInfo(
            @RequestHeader("token")String token,
            @NotNull  Integer recordId){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");
        RecordInfoParams recordInfoParams = sickUserService.userGetRecordInfo(loginId, recordId);
        return ApiResult.successWithData(recordInfoParams);
    }

    @RequireToken
    @ApiOperation(value = "患者获取全部医生列表(后端已调)",notes = "患者获取医生列表",httpMethod = "get")
    @GetMapping(value = "/userGetDoctorsList",produces = "application/json;charset=utf-8")
    public ApiResult<List<UserDoctorsItem>> userGetDoctorsList(
            @RequestHeader("token")String token,
            @NotNull @RequestParam(value ="isFollow",required = false) Integer isFollow){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");
        List<UserDoctorsItem> userDoctorsItems = sickUserService.userGetDoctorsList(loginId,isFollow);
        return ApiResult.successWithData(userDoctorsItems);
    }

    @RequireToken
    @ApiOperation(value = "患者关注医生(后端已调)",notes = "患者关注医生",httpMethod = "get")
    @PostMapping(value = "/userFollowDoctor",produces = "application/json;charset=utf-8")
    public ApiResult userFollowDoctor(
            @RequestHeader("token")String token,
            @NotNull Integer doctorId
    ){
        Object token1 = redisUtil.get(token);
        Map<String, Object> map = (Map<String, Object>) token1;
        Integer loginId = (Integer) map.get("loginId");
        boolean b = sickUserService.userFollowDoctor(loginId, doctorId);
        return ApiResult.withBoolean(b);
    }

    @ApiOperation(value = "用户支付接口",notes = "用户支付接口接口",httpMethod = "get")
    @PostMapping(value = "/userPayCard",produces = "application/json;charset=utf-8")
    public ApiResult userPayCard(
            String orderNo
    ){
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient
                (
                        "https://openapi.alipay.com/gateway.do",
                        AlipayConfig.app_id,
                        AlipayConfig.merchant_private_key,
                        "json",
                        AlipayConfig.charset,
                        AlipayConfig.alipay_public_key,
                        "RSA2");
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("我是测试数据");
        model.setSubject("App支付测试Java");
        //输入自己生成的订单号
        model.setOutTradeNo(orderNo);
        System.out.println("充值卡订单表ID："+orderNo);
        model.setTimeoutExpress("30m");
        //输入订单金额
        Double money = sickUserService.selectMoney(orderNo);
        model.setTotalAmount(money.toString());
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl("http://zhoudw.vip/sickuser/user/aliPayCallBack");
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            String body = response.getBody();
            return  ApiResult.successWithData(body);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return ApiResult.failure("支付失败");
        }
    }

    @ApiIgnore
    @ApiOperation(value = "支付宝支付回调",notes = "支付宝支付回调接口",httpMethod = "post")
    @PostMapping(value = "/aliPayCallBack",produces = "application/json;charset=utf-8")
    public void aliPayCallBack(HttpServletRequest request){
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }

            params.put(name, valueStr);
        }
        try {
            boolean flag = AlipaySignature.rsaCheckV1(params,
                    AlipayConfig.ali_public_key,
                    AlipayConfig.charset,"RSA2");
            if(flag){
                //然后在这里修改本地的订单状态
                System.out.println(params);
                String time = params.get("gmt_create");//订单支付时间
                String orderId = params.get("out_trade_no");//订单ID
                String money = params.get("invoice_amount");//金额
                System.out.println("支付验证成功");

                Integer id = sickUserService.addTransaction(orderId,time,money);
                System.out.println(id);

            }else {
                System.out.println("支付验证失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
    }



    /*private  ApiResult goRecharge(@RequestHeader("token") String token,Integer cardId){
        Map<String, Object> map = (Map<String, Object>) redisUtil.get(token);
        Integer loginId = (Integer) map.get("loginId");
        ResultOrder order = accountInfoService.goRecharge(loginId,cardId);
        return ApiResult.successWithData("成功",order);
    }*/
}
